<!DOCTYPE HTML>
<html>
<head>
<title>decagons</title>
<!--

-->
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta content="width=device-width; initial-scale=1.0;  maximum-scale=1.0; user-scalable=0;" name="viewport" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<style>
	body { padding:0px; margin:0px; color: white; background-color: black; }
	input { 
		font-size:16px;
		padding: 0px;
	}
	* {font-family: sans-serif}
	form { padding:0px; margin:0px; }
</style>
<script src="../../lib/canvas.js"></script>
<script>
	var opt = new Object();
	opt.border = true;
	function console_log(s) {
		var c = document.getElementById("console");
		var o = "" + s;
		o.replace(/&/, '&amp;');
		o.replace(/</, '&lt;');
		o.replace(/>/, '&gt;');
		o.replace(/'/, '&apos;');
		o.replace(/"/, '&quot;');
		c.innerHTML += o + '<br />';
	}
	var phi;
	function init() {
		canvas_init();
		phi = Math.sqrt(5) + 1;
		phi /= 2;

		ctx.strokeStyle = "white";
		//ctx.globalCompositeOperation = 'lighter';
		ctx.translate(canvas.width / 2, canvas.height / 2);

		var theta = Math.PI / 2;
		var c = {x: 0, y: 0};
		var cr = 120;
		var decs = new Array();
		p = draw_cartwheel(cr, c.x, c.y, Math.PI / 2);
		decs.push(p);
		var m = get_midpoints(p);
		var d = get_distance(c, m[0]);
		p = get_regular_polygon_points(10, c.x, c.y, 2 * d, theta + Math.PI / 10)
		decs.push(draw_cartwheel(cr, p[0].x, p[0].y, theta - 3 * Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[2].x, p[2].y, theta - 4 * Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[4].x, p[4].y, theta + Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[6].x, p[6].y, theta));
		decs.push(draw_cartwheel(cr, p[8].x, p[8].y, theta + 2 * Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[1].x, p[1].y, theta - 2 * Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[3].x, p[3].y, theta));
		decs.push(draw_cartwheel(cr, p[5].x, p[5].y, theta - Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[7].x, p[7].y, theta + 4 * Math.PI / 5));
		decs.push(draw_cartwheel(cr, p[9].x, p[9].y, theta + 3 * Math.PI / 5));
		ctx.strokeStyle = "white";
		ctx.lineWidth = 2;
		for (i in decs) { draw_polygon(decs[i]); }
	}

	function draw_pentagon(r, x, y, theta) {
		return draw_polygon(
			get_regular_polygon_points(5, x, y, r, theta)
		);
	}

	function get_distance(p1, p2) {
		var dx = (p2.x - p1.x);
		var dy = (p2.y - p1.y);
		return Math.sqrt(dx * dx + dy * dy);
	}

	function draw_cartwheel(r, x, y, theta) {
		var i;
		var p = get_regular_polygon_points(10, x, y, r, theta);
		p.unshift(p.pop());
		//draw_polygon(p);

		var tile_r = get_distance(p[0], p[1]) * (phi - 1);

		opt = {border: true};
		ctx.strokeStyle = "rgb(0, 0, 255)";
		draw_cartwheel_tiles(tile_r, p[6].x, p[6].y, theta);

		opt = {half: true};
		ctx.strokeStyle = "rgb(27, 0, 63)";
		draw_cartwheel_tiles(tile_r, p[6].x, p[6].y, theta);

		opt = {arc_a: true};
		ctx.strokeStyle = "rgb(0, 127, 0)";
		draw_cartwheel_tiles(tile_r, p[6].x, p[6].y, theta);

		opt = {arc_b: true};
		ctx.strokeStyle = "rgb(255, 0, 0)";
		draw_cartwheel_tiles(tile_r, p[6].x, p[6].y, theta);

		ctx.strokeStyle = "rgb(255, 255, 255)";

		var m = get_midpoints(p);
		//draw_polygon(m);

		// find the ammann bars
		ctx.strokeStyle = "rgb(255, 255, 0)";
		var b = new Array();
		for (i = 0; i < 10; i += 2) {
			b.push([
				[m[i], m[(i + 3) % 10]],
				[m[(i + 5) % 10], m[(i + 8) % 10]]
			]);
		}
		// add the middle ammann bars
		var a = [0, 1];
		var p1, p2, e1, e2, f1, f2;
		for (i = 0; i < b.length; ++i) { 
			a.reverse();
			p1 = get_midpoint_r(
				1 - phi, 
				b[i][a[1]][1], 
				b[i][a[0]][0]
			);
			p2 = get_midpoint_r(
				1 - phi, 
				b[i][a[1]][0], 
				b[i][a[0]][1]
			);
			// find the lines we want to intersect

			e1 = p[(2 * i) % 10]; 
			e2 = p[(2 * i + 9) % 10];
			f1 = p[(2 * i + 4) % 10]
			f2 = p[(2 * i + 5) % 10];

			b[i].push([
				get_intersection(p1, p2, e1, e2),
				get_intersection(p1, p2, f1, f2)
			]);
		}

		ctx.save();
		var j = 2;
		for (i in b) {
			//ctx.strokeStyle = rainbow_color(i/b.length);
			ctx.beginPath();
			for (j in b[i]) {
				ctx.moveTo(b[i][j][0].x, b[i][j][0].y);
				ctx.lineTo(b[i][j][1].x, b[i][j][1].y);
			}
			ctx.stroke();

		}
		ctx.restore();
		p.push(p.shift());
		return p;
	}

	function draw_cartwheel_tiles (r, x, y, theta) {
		ctx.save();
		ctx.translate(x, y);
		ctx.rotate(3 * Math.PI / 10 - theta);
		var t = 0;

		var n = draw_dart(r, 0, 0, t);
		var o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.br;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.br;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.darts.bl;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.br;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.br;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.darts.bl;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.br;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.tr;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.bl;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.tr;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.bl;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.br;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.tr;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.darts.tr;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.darts.bl;
		n = draw_dart(r, o.x, o.y, o.theta);
		o = n.kites.tl;
		n = draw_kite(r, o.x, o.y, o.theta);
		o = n.kites.bl;
		n = draw_kite(r, o.x, o.y, o.theta);

		ctx.restore();
	}

	

	function draw_decagon(r, x, y, theta) {
		return draw_polygon(
			get_regular_polygon_points(10, x, y, r, theta)
		);
	}

	function get_midpoints(p) {
		var i;
		var o = new Array();
		if (p.length < 2) { return o; }
		var pp = p[0];
		for (i = 1; i < p.length; ++i) {
			o.push(get_midpoint(pp, p[i]));
			pp = p[i];
		}
		o.push(get_midpoint(pp, p[0]));
		return o;
	}

	function get_midpoint(p1, p2) {
		var o = new Object();
		o.x = (p1.x + p2.x) / 2;
		o.y = (p1.y + p2.y) / 2;
		return o;
	}

	function get_midpoint_r(r, p1, p2) {
		var dx = (p2.x - p1.x);
		var dy = (p2.y - p1.y);
		var d = Math.sqrt(dx * dx + dy * dy);
		var th = Math.atan2(dy, dx);
		var o = new Object();
		o.x = p2.x + r * d * Math.cos(th);
		o.y = p2.y + r * d * Math.sin(th);
		return o;
	}

	function get_intersection(p1, p2, p3, p4) {
		// p1 and p2 are on one line,
		// p3 and p4 are on the other
		
		var d = (
			(p4.y - p3.y) * (p2.x - p1.x) -
			(p4.x - p3.x) * (p2.y - p1.y)
		);
		if (0 == d) { return null; }

		var u = (
			(p4.x - p3.x) * (p1.y - p3.y) -
			(p4.y - p3.y) * (p1.x - p3.x)
		) / d;

		var o = new Object();
		o.x = p1.x + u * (p2.x - p1.x);
		o.y = p1.y + u * (p2.y - p1.y);

		return o;
	}

	function get_regular_polygon_points(sides, x, y, r, theta) {
		var p = new Array();
		var th;
		var i;
		for (i = 0; i < sides; ++i) {
			th = theta + i * 2 * Math.PI / sides;
			p[i] = new Object();
			p[i].x = x + r * Math.cos(th);
			p[i].y = y - r * Math.sin(th);
		}
		return p;
	}

	function draw_polygon(p) {
		ctx.save();
		ctx.beginPath();
		ctx.moveTo(p[0].x, p[0].y);
		for (i = 1; i < p.length; ++i) {
			ctx.lineTo(p[i].x, p[i].y);
			//alert(p[i].x + "," + p[i].y);
		}
		ctx.closePath();
		ctx.stroke();
		ctx.restore();
		return p;
	}

function draw_dart(r, x, y, theta, hide) {
		// return a list of possible neighboring tiles
		var u = r / (1 + phi);
		var o = new Array();

		o.kites = new Array();
		o.darts = new Array();
		o.darts.bl = {x: x, y:y, theta: theta - 2 * Math.PI / 5};
		o.darts.br = {x: x, y:y, theta: theta + 2 * Math.PI / 5};
		o.darts.tl = o.darts.bl;
		o.darts.tr = o.darts.br;

		o.kites.bl = {x: x, y:y, theta: theta + Math.PI};
		o.kites.br = {x: x, y:y, theta: theta + Math.PI};

		var hyp;
		var t;

		hyp = u * (1 + phi);

		t = - theta - 4 * Math.PI / 5;
		o.kites.bl.x = x + hyp * Math.sin(t);
		o.kites.bl.y = y + hyp * Math.cos(t);

		t = - theta + 4 * Math.PI / 5;
		o.kites.br.x = x + hyp * Math.sin(t);
		o.kites.br.y = y + hyp * Math.cos(t);

		o.kites.tl = {x: x, y:y, theta: theta - 4 * Math.PI / 5};
		o.kites.tr = {x: x, y:y, theta: theta + 4 * Math.PI / 5};

		hyp = u * (1 + 2 * phi);
		t = - theta + Math.PI;
		o.kites.tl.x = x + hyp * Math.sin(t);
		o.kites.tl.y = y + hyp * Math.cos(t);
		o.kites.tr.x = x + hyp * Math.sin(t);
		o.kites.tr.y = y + hyp * Math.cos(t);

		if (null != hide) { return o; }

		if (null == opt || opt.half) {
			ctx.save();
			ctx.translate(x, y);
			ctx.rotate(theta + Math.PI);
			ctx.beginPath();
			ctx.moveTo(0, 0);
			ctx.lineTo(0, u * phi);
			ctx.stroke();
			ctx.restore();
		}

		if (null == opt || opt.border) {
		ctx.save();
		ctx.translate(x, y);
		ctx.rotate(theta + Math.PI);

		ctx.beginPath();
		ctx.moveTo(0, 0);
		ctx.rotate(Math.PI/5);
		ctx.translate(0, u * (phi + 1));
		ctx.lineTo(0, 0);
		ctx.rotate(-4 * Math.PI/5);
		ctx.translate(0, u * phi);
		ctx.lineTo(0, 0);
		ctx.rotate( Math.PI/5);
		ctx.translate(0, u * phi);
		ctx.lineTo(0, 0);
		ctx.rotate(-4 * Math.PI/5);
		ctx.translate(0, u * (1 + phi));
		ctx.lineTo(0, 0);
		ctx.stroke();
		ctx.restore();
		}

		if (null == opt || opt.arc_a) {
		ctx.save();
		ctx.translate(x, y);
		ctx.moveTo(0, 0);
		ctx.rotate(theta + Math.PI);
		ctx.rotate(3 * Math.PI/10);
		ctx.beginPath();
		ctx.arc(0, 0, u, 0, 2 * Math.PI/5, false);
		ctx.stroke();
		ctx.restore();
		}

		if (null == opt || opt.arc_b) {
		ctx.save();
		ctx.translate(x, y);
		ctx.moveTo(0, 0);
		ctx.rotate(theta + Math.PI);
		ctx.translate(0, u * (1 + 1/ phi));
		ctx.rotate(9 * Math.PI/10);
		ctx.beginPath();
		ctx.arc(0, 0, u / phi, 0, 6 * Math.PI/5, false);
		ctx.stroke();
		ctx.restore();
		}

		return o;
	}

	function draw_kite(r, x, y, theta, hide) {

		var u = r / (1 + phi);
		// return a list of possible neighboring tiles
		var o = new Array();
		o.kites = new Array();
		o.darts = new Array();
		o.kites.bl = {x: x, y:y, theta: theta - 2 * Math.PI/5};
		o.kites.br = {x: x, y:y, theta: theta + 2 * Math.PI/5};
		o.kites.tl = {x: x, y:y, theta: theta + 4 * Math.PI/5};
		o.kites.tr = {x: x, y:y, theta: theta - 4 * Math.PI/5};
		var hyp = 2 * u * (1 + phi) * Math.cos(Math.PI/10);
		var t;
		t = - theta - 9 * Math.PI/10;
		o.kites.tl.x = x + hyp * Math.sin(t);
		o.kites.tl.y = y + hyp * Math.cos(t);
		t = - theta + 9 * Math.PI/10;
		o.kites.tr.x = x + hyp * Math.sin(t);
		o.kites.tr.y = y + hyp * Math.cos(t);

		hyp = u * (1 + phi);

		o.darts.bl = {x: x, y:y, theta: theta + Math.PI};
		o.darts.br = {x: x, y:y, theta: theta + Math.PI};

		t = - theta - 4 * Math.PI/5;
		o.darts.bl.x = x + hyp * Math.sin(t);
		o.darts.bl.y = y + hyp * Math.cos(t);

		t = - theta + 4 * Math.PI/5;
		o.darts.br.x = x + hyp * Math.sin(t);
		o.darts.br.y = y + hyp * Math.cos(t);

		o.darts.tl = {x: x, y:y, theta: theta + 4 * Math.PI / 5};
		o.darts.tr = {x: x, y:y, theta: theta - 4 * Math.PI / 5};

		hyp = u * (1 + 2 * phi);

		t = - theta - 4 * Math.PI/5;
		o.darts.tl.x = x + hyp * Math.sin(t);
		o.darts.tl.y = y + hyp * Math.cos(t);

		t = - theta + 4 * Math.PI/5;
		o.darts.tr.x = x + hyp * Math.sin(t);
		o.darts.tr.y = y + hyp * Math.cos(t);

		if (null != hide) { return o; }

		if (null == opt || opt.half) {
			ctx.save();
			ctx.translate(x, y);
			ctx.rotate(theta + Math.PI);
			ctx.beginPath();
			ctx.moveTo(0, 0);
			ctx.lineTo(0, u * (1 + phi));
			ctx.stroke();
			ctx.restore();
		}

		if (null == opt || opt.border) {
		ctx.save();
		ctx.translate(x, y);
		ctx.rotate(theta + Math.PI);
		ctx.beginPath();
		ctx.moveTo(0, 0);
		ctx.rotate(Math.PI/5);
		ctx.translate(0, u * (phi + 1));
		ctx.lineTo(0, 0);
		ctx.rotate(-3 * Math.PI/5);
		ctx.translate(0, u * phi);
		ctx.lineTo(0, 0);
		ctx.rotate(- Math.PI/5);
		ctx.translate(0, u * phi);
		ctx.lineTo(0, 0);
		ctx.rotate(-3 * Math.PI/5);
		ctx.translate(0, u * (1 + phi));
		ctx.lineTo(0, 0);
		ctx.stroke();
		ctx.restore();
		}

		if (null == opt || opt.arc_a) {
		ctx.save();
		ctx.translate(x, y);
		ctx.moveTo(0, 0);
		ctx.rotate(theta + Math.PI);
		ctx.rotate(3 * Math.PI/10);
		ctx.beginPath();
		ctx.arc(0, 0, u * phi, 0, 2 * Math.PI/5, false);
		ctx.stroke();
		ctx.restore();
		}

		if (null == opt || opt.arc_b) {
		ctx.save();
		ctx.translate(x, y);
		ctx.moveTo(0, 0);
		ctx.rotate(theta + Math.PI);
		ctx.translate(0, u * (1 + phi));
		ctx.rotate(11 * Math.PI/10);
		ctx.beginPath();
		ctx.arc(0, 0, u , 0, 4 * Math.PI/5, false);
		ctx.stroke();
		ctx.restore();
		}

		return o;
	}

	

</script>
</head>
<body onload="init()">
	<canvas id="canvas" class="canvas"  width="720" height="720"></canvas>
	<div id="console"></div>
</body>
</html>
